/*
'  DotNetNuke -  http://www.dotnetnuke.com
'  Copyright (c) 2002-2011
'  by DotNetNuke Corporation
' 
'  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
'  documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
'  the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
'  to permit persons to whom the Software is furnished to do so, subject to the following conditions:
' 
'  The above copyright notice and this permission notice shall be included in all copies or substantial portions 
'  of the Software.
' 
'  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
'  TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
'  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
'  CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
'  DEALINGS IN THE SOFTWARE.
*/

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Reflection;
using DotNetNuke.Common;
using DotNetNuke.Common.Utilities;

namespace DotNetNuke.Modules.Store.Components
{
	/// <summary>
	/// Summary description for NavigateWrapper.
	/// </summary>
	public abstract class NavigateWrapper
	{
		#region Constructors

		public NavigateWrapper()
		{
		}

		public NavigateWrapper(NameValueCollection queryString)
		{
			LoadQueryString(queryString);
		}

		public NavigateWrapper(int ModuleId, NameValueCollection queryString)
		{
            _moduleId = ModuleId;
			LoadQueryString(queryString);
		}

		#endregion

		#region Declarations

		private int _tabId = Null.NullInteger;
		private int _moduleId = Null.NullInteger;
		private string _controlKey = Null.NullString;

		#endregion

		#region Public Properties

		public int TabId
		{
			get { return _tabId; }
			set { _tabId = value; }
		}

		public int ModuleId
		{
            get { return _moduleId; }
            set { _moduleId = value; }
		}

		public string ControlKey
		{
			get { return _controlKey; }
			set { _controlKey = value; }
		}

		#endregion

		#region Public Methods

		/// <summary>
		/// Parses the QueryString parameters and sets properties, if they exist,
		/// in the derived object.
		/// </summary>
		/// <param name="queryString"></param>
		public void LoadQueryString(NameValueCollection queryString)
		{
            PropertyInfo[] propertyList = GetProperties();
            //string queryValue = null;
            object value = null;
			// Iterate thru all properties for this type
			foreach(PropertyInfo property in propertyList)
			{
				// Do we have a value for this property?
                value = queryString[property.Name];
                if (value != null)
                    property.SetValue(this, Convert.ChangeType(value, property.PropertyType), null);
			}
		}

		/// <summary>
		/// Gets an array of query string parameters to be used with the 
		/// DotNetNuke NavigateUrl(), EditUrl() etc.
		/// </summary>
		/// <returns></returns>
		public string[] GetNavigateParameters()
		{
			return GetNavigateParameters(new StringDictionary());
		}

		/// <summary>
		/// Gets an array of query string parameters to be used with the 
		/// DotNetNuke NavigateUrl(), EditUrl() etc.
		/// </summary>
		/// <param name="replaceParams">List of parameters to use as replacements for existing parameters.</param>
		/// <returns></returns>
		public string[] GetNavigateParameters(StringDictionary replaceParams)
		{
			PropertyInfo[] propertyList = GetProperties();
            List<string> settingList = new List<string>(propertyList.Length);
            string propertyName = null;
            string replaceValue = null;
            object propertyValue = null;
			// Iterate thru all properties for this type
			foreach(PropertyInfo property in propertyList)
			{
                propertyName = property.Name;
                if (replaceParams.ContainsKey(propertyName))
				{
                    replaceValue = replaceParams[propertyName];
                    if (string.IsNullOrEmpty(replaceValue) == false)
                    {
                        // Add name and value pair for NavigateUrl() parameters
                        if (propertyName == "ModuleId")
                            settingList.Add("mid=" + replaceParams[propertyName]);
                        else
                            settingList.Add(propertyName + "=" + replaceParams[propertyName]);
                    }
				}
				else
				{
                    if (propertyName != "TabId" && propertyName != "ControlKey")
                    {
                        propertyValue = property.GetValue(this, null);
                        if (Null.IsNull(propertyValue) == false)
                        {
                            // Add name and value pair for NavigateUrl() parameters
                            if (propertyName == "ModuleId")
                                settingList.Add("mid=" + propertyValue.ToString());
                            else
                                settingList.Add(propertyName + "=" + propertyValue.ToString());
                        }
                    }
				}
			}
			// Cast to string array and return
			return (settingList.ToArray());			
		}

		/// <summary>
		/// Gets the url for navigation including the appropriate parameters.
		/// </summary>
		/// <returns></returns>
		public string GetNavigationUrl()
		{
			return Globals.NavigateURL(_tabId, _controlKey, GetNavigateParameters()).ToLower();
		}

		/// <summary>
		/// Gets the url for navigation including the appropriate parameters.
		/// </summary>
		/// <param name="replaceParams">List of parameters to use as replacements for existing parameters.</param>
		/// <returns></returns>
		public string GetNavigationUrl(StringDictionary replaceParams)
		{
			return Globals.NavigateURL(_tabId, _controlKey, GetNavigateParameters(replaceParams)).ToLower();
		}

        /// <summary>
        /// Gets the url for navigation including the appropriate parameters.
        /// </summary>
        /// <param name="replaceParams">List of parameters to use as replacements for existing parameters.</param>
        /// <returns></returns>
        public string GetNavigationUrl(int TabID, StringDictionary replaceParams)
        {
            return Globals.NavigateURL(TabID, _controlKey, GetNavigateParameters(replaceParams)).ToLower();
        }

        public string GetEditUrl()
        {
            return GetEditUrl("", "", _controlKey);
        }

        public string GetEditUrl(int ModuleId)
        {
            return GetEditUrl(ModuleId, "", "", _controlKey);
        }

        public string GetEditUrl(string ControlKey)
        {
            return GetEditUrl("", "", ControlKey);
        }

        public string GetEditUrl(int ModuleId, string ControlKey)
        {
            return GetEditUrl(ModuleId, "", "", ControlKey);
        }

        public string GetEditUrl(string KeyName, string KeyValue)
        {
            return GetEditUrl(KeyName, KeyValue, _controlKey);
        }

        public string GetEditUrl(int ModuleId, string KeyName, string KeyValue)
        {
            return GetEditUrl(ModuleId, KeyName, KeyValue, _controlKey);
        }

        public string GetEditUrl(string KeyName, string KeyValue, string ControlKey)
        {
            if (_moduleId == Null.NullInteger)
                throw new Exception("GetEditUrl: ModuleId is required!");

            StringDictionary replaceParams = new StringDictionary();
            replaceParams.Add("moduleid", _moduleId.ToString());

            if (KeyName != "" && KeyValue != "")
                replaceParams.Add(KeyName, KeyValue);

            if (string.IsNullOrEmpty(ControlKey) == true)
                ControlKey = "Edit";

            return Globals.NavigateURL(_tabId, ControlKey, GetNavigateParameters(replaceParams));
        }

        public string GetEditUrl(int ModuleId, string KeyName, string KeyValue, string ControlKey)
        {
            _moduleId = ModuleId;
            return GetEditUrl(KeyName, KeyValue, ControlKey);
        }

		#endregion

        #region Private Methods

        private PropertyInfo[] GetProperties()
        {
            string cacheKey = "Store_" + this.GetType().FullName;
            PropertyInfo[] propertyList = (PropertyInfo[])DataCache.GetCache(cacheKey);
            if (propertyList == null)
            {
                propertyList = this.GetType().GetProperties();
                DataCache.SetCache(cacheKey, propertyList);
            }
            return propertyList;
        }

        #endregion
    }
}
